#include <bits/stdc++.h>
using namespace std;
//https://www.nowcoder.com/practice/f0db4c36573d459cae44ac90b90c6212?tpId=182&tqId=34789&ru=/exam/oj
// int main()
// {
//     string s1,s2,s3;
//     getline(cin,s1);
//     cin>>s2;
//     int j=0;
//     for(auto it2=s2.begin();it2!=s2.end();it2++)
//     {
//         for(auto it1=s1.begin();it1!=s1.end();it1++)
//         {
//             if(*it1==*it2)it1=s1.erase(it1);
//             if(it1==s1.end())break;
//         }
//     }
//     cout<<s1<<endl;
//     return 0;
// }

//写法二
//哈希表标记需要删除的字符，然后遍历主串，打印为true的字符
// int main()
// {
//     string s1,s2,ret;
//     getline(cin,s1);getline(cin,s2);
//     bool hash[300]={0};
//     for(char ch:s2)hash[ch]=true;
//     for(char ch:s1)
//     {
//         if(!hash[ch])ret+=ch;
//     }
//     cout<<ret<<endl;
// }
//https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&ru=/exam/oj

struct ListNode
{
    int val;
    struct ListNode* next;
    ListNode(int x):val(x),next(nullptr){} 
};
//通过计数得到每个链表长度的差值，然后先让长的那个走差值步
//此时两个链表同时开始走，当第一次两个指针指向的节点值相同时，就说明找到相同的节点了
// class Solution {
//     public:
//         ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
//             if(!pHead1||!pHead2)return nullptr;
//             ListNode* cur1=pHead1,*cur2=pHead2;
//             int count1=0,count2=0,diff=0;
//             while(cur1)
//             {
//                 count1++;cur1=cur1->next;
//             }
//             while(cur2)
//             {
//                 count2++;cur2=cur2->next;
//             }
//             cur1=pHead1,cur2=pHead2;
//             if(count1>count2)
//             {
//                 diff=count1-count2;
//                 while(diff)
//                 {
//                     diff--;cur1=cur1->next;
//                 }
//             }
//             if(count1<count2)
//             {
//                 diff=count2-count1;
//                 while(diff)
//                 {
//                     diff--;cur2=cur2->next;
//                 }
//             }
//             while(cur1&&cur2)
//             {
//                 if(cur1->val==cur2->val)break;
//                 cur1=cur1->next;
//                 cur2=cur2->next;
//             }
//             return cur1;
//         }
//     };

//通过等量关系x1+x+x2==x2+x+x1;
//得到存在相同节点一定能相遇，否则会返回空
// class Solution {
//     public:
//         ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
//             if(!pHead1 || !pHead2)return nullptr;
//             ListNode* cur1 = pHead1, *cur2 = pHead2;
//             while(cur1 != cur2)
//             {
//                  //这里一定要在为空时指向链表的头节点，而不是cur1或cur2
//                 cur1 = (cur1 == nullptr ? pHead1 : cur1->next);
//                 cur2 = (cur2 == nullptr ? pHead2 : cur2->next);
//             }
//             return cur1;
//         }
//     };

// int main()
// {
//     // 创建链表 1: 1 -> 2 -> 3 -> 6 -> 7
//     ListNode* head1 = new ListNode(1);
//     head1->next = new ListNode(2);
//     head1->next->next = new ListNode(3);

//     // 创建链表 2: 4 -> 5 -> 6 -> 7
//     ListNode* head2 = new ListNode(4);
//     head2->next = new ListNode(5);

//     // 共同部分: 6 -> 7
//     ListNode* common = new ListNode(6);
//     common->next = new ListNode(7);

//     // 将共同部分连接到两个链表
//     head1->next->next->next = common;
//     head2->next->next = common;
//     ListNode* ret=Solution().FindFirstCommonNode(head1,head2);
//     if(ret==nullptr)cout<<"ret is null"<<endl;
//     while(ret)
//     {
//         cout<<ret->val<<" ";
//         ret=ret->next;
//     }
//     // freeList(head1);
//     return 0;
// }

//动态规划-多状态线性dp
//s[i]表示[0,i-1]内有多少个字符s，当本位是s时，s[i]=s[i-1]+i,否则s[i]=s[i-1]
//sh[i]表示[0,i-1]内有多少个字符sh，当本位是h时，sh[i]=s[i]+sh[i-1],否则sh[i]=sh[i-1]
//shy[i]表示[0,i-1]内有多少个字符shy，当本位是y时，shy[i]=sh[i]+shy[i-1],否则shy[i]=shy[i-1]

//如何初始化，
//当字符串s1第一位是's'时，将s[i]初始化为1，否则初始化为0
//由于sh[i]和shy[i]存储的是[0,i-1]区间内的"sh"和"shy"的数量，所以置0即可
const int maxlen=300010;
//
// int main() 
// {
//     int m;cin>>m;
//     string s1;cin>>s1;
//     vector<long long> s(maxlen,0),sh(maxlen,0),shy(maxlen,0);
//     if(s1[0]=='s')s[0]=1;
//     else s[0]=0;
//     sh[0]=shy[0]=0;
//     for(int i=1;i<=s1.size();i++)
//     {
//         char ch=s1[i];
//         if(ch=='s')s[i]+=s[i-1]+1;
//         else s[i]+=s[i-1];

//         if(ch=='h')sh[i]+=s[i-1]+sh[i-1];
//         else sh[i]+=sh[i-1];

//         if(ch=='y')shy[i]+=shy[i-1]+sh[i-1];
//         else shy[i]+=shy[i-1];
//     }
//     cout<<shy[m]<<endl;;
//     return 0;
// }


//空间优化版本
int main()
{
    int n;cin>>n;
    string s1;cin>>s1;
    long long s=0,sh=0,shy=0;
    for(int i=0;i<s1.size();i++)
    {
        if(s1[i]=='s')s++;
        else if(s1[i]=='h')sh+=s;
        else if(s1[i]=='y')shy+=sh;
    }
    cout<<shy<<endl;
    return 0;
}